package com.xxx.interceptor;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.xxx.common.Const;
import com.xxx.common.UserAuth;
import com.xxx.model.SysMenu;
import com.xxx.service.SysMenuService;
import com.xxx.service.SysRoleMenuService;

/**
 * 拦截器配置
 * @author kang
 * @date 2017-03-05
 */
@Component
public class UserSecurityInterceptor extends HandlerInterceptorAdapter {
	
	@Autowired
	private SysMenuService sysMenuService;	
	
	@Autowired
	private SysRoleMenuService sysRoleMenuService;

	@Value("${server.context-path:}")
	private String contextPath; 
	
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		if (handler instanceof HandlerMethod) {
			UserAuth.refreshUserAuth(request, response);
			HandlerMethod hm = (HandlerMethod) handler;
			Class<?> clazz = hm.getBeanType();
			Method m = hm.getMethod();
			if(clazz != null && m != null){
				StringBuilder sb = new StringBuilder(contextPath);
				boolean isClzAnnotation = clazz.isAnnotationPresent(UserAuthority.class);
				boolean isMethondAnnotation = m.isAnnotationPresent(UserAuthority.class);
				UserAuthority authority = null;
				if (isClzAnnotation) {
					authority = clazz.getAnnotation(UserAuthority.class);
				}else if (isMethondAnnotation) {
					authority = m.getAnnotation(UserAuthority.class);
				} 
				long userid = UserAuth.getUserid(request);
				if (authority != null) {
					if (AuthorityType.NoAuthority == authority.authorityType()) {
						// 不验证权限，验证是否登录
						if (userid == Const.DEFAULT_LONG_NULL) {
							// 未登录,跳转去登录
							sb.append("/account/login.html");
							response.getWriter().write("<script>top.location.href='" + sb.toString() + "'</script>");
							return false;
						}
						return true;
					} else if (AuthorityType.NoValidate == authority.authorityType()) {
						// 标记为不验证,放行
						return true;
					}
				}
				if (userid == Const.DEFAULT_LONG_NULL) {
					// 未登录,跳转去登录
					sb.append("/account/login.html");
					response.getWriter().write("<script>top.location.href='" + sb.toString() + "'</script>");
					return false;
				}else{
					//判断权限
					boolean flag = isAuthority(userid, request);
					if (!flag) {
						// 没权限跳转到404页面
						sb.append("/error/404");
						response.getWriter().write("<script>top.location.href='" + sb.toString() + "'</script>");
					}
					return flag;
				} 
			}
		}
		return false;
	}

	/**
	 * @Title: isAuthority 
	 * @Description: 判断用户有没有角色
	 * @param userid
	 * @return
	 * @throws Exception
	 */
	private boolean isAuthority(long userid, HttpServletRequest request) throws Exception {
		boolean flag = false;
		String requestUrl = request.getRequestURI(); // 得到请求的资源
		//截取当前请求URL。
		String url = getJurisdictionUrl(requestUrl);
		if(StringUtils.isNotBlank(url)){
			url = url.replaceAll(contextPath, "");
			if (url.startsWith("/")){
				url = url.substring(1, url.length());
			}
			Map<String, Object> whereMap = new HashMap<>();
			whereMap.put("status", 1);													
			List<SysMenu> menuList = sysMenuService.getList(whereMap);			 //所有启用状态的菜单
			Set<Long> userRoleMenu = sysRoleMenuService.getUserRoleMenu(userid); //该用户所以的菜单
			for (SysMenu sysMenu : menuList) {
				if (userRoleMenu.contains(sysMenu.getId()) && sysMenu.getMenuurl().contains(url)) {
					return true;
				}
			}
		}
		return flag;
	}
	
	/**
	 * @Title: getJurisdictionUrl 
	 * @Description: 获取权限路径  比如:"/manage/index.html"->返回 "/manage"
	 * @param requestUrl
	 * @return
	 */
	private static String getJurisdictionUrl(String requestUrl){
		int indexOf = requestUrl.indexOf("/");
		int lastIndexOf = requestUrl.lastIndexOf("/");
		if(StringUtils.isNotBlank(requestUrl) && lastIndexOf >= indexOf && indexOf > -1 ){
			return requestUrl.substring(indexOf, lastIndexOf);
		}
		return null;
	 }

}
